package arbori;

import Visitor.Visitor;

/**
 * Clasa Nod
 * Structura de date folosita pentru a repreznta o functie algebrica este 
 * de arbore binar,unde frunzele arborelui reprezinta functia identica,
 * nodurile cu doi fii reprezinta operatori aritmetici elementari
 * iar nodurile cu un singur fiu functii matematice elementare 
 * (putere,logaritm,sin, etc.).
 * clasa Nod va fi clasa parinte pentru clasele Operator si Functie.
 * Atributele clasei sunt de tipul protected:
 * ns - variabila de tipul Nod reprezentand fiul stang al nodului
 * nd - reprezinta fiul drept al nodului
 * variabila x de tipul double este folosit pentru a memora argumentul
 * functiei folosit la diferite calcule non simbolice.
 * 
 * @author Sorica Alexandra
 *
 */

public abstract class Nod {
	
	/**
	 * This node represents the node from the left side. 
	 * If ns is null then the nod is a function
	 */
	
	protected Nod ns;
	
	/**
	 * This node represents the node from the right side.
	 * If nd is null then the node is a leaf.
	 */
	
	protected Nod nd;
	
	/**
	 * x represents the function parameter. 
	 */
	
	protected  double x;
	
	/**
	 * functia getNs este folosita pentru a obtine valoarea fiului stang al unui nod
	 * @return returneaza o variabila de tipul Nod reprezentand subarborele stang
	 */
	
	public Nod getNs() {
		return ns;
		}
	
	/**
	 * functia setNs este folosita pentru a seta valoarea fiului stang al unui nod
	 * @param Ns variabila de tipul Nod transmisa ca parametru reprezinta valoarea 
	 * fiului stang al nodului
	 */
	
	public void setNs(Nod ns) {
		this.ns = ns;
		}
	
	/**
	 * functia getNd este folosita pentru a obtine valoarea fiului drept al unui nod
	 * @return returneaza o variabila de tipul Nod reprezentand subarborele drept
	 */
	
	public Nod getNd(){
		return nd;
		}
	
	/**
	 * functia setNd este folosita pentru a seta valoarea fiului drept al unui nod
	 * @param Nd variabila de tipul Nod transmisa ca parametru reprezinta valoarea 
	 * fiului drept al nodului
	 */
	
	public void setNd(Nod nd) {
		this.nd = nd;
		}
	
	/**
	 * metoda getX() se foloseste pt a obtine valoarea atributui X
	 * @return returneaza o variabila de tip double
	 */
	
	public double getX() {
		return x;
		}
	
	/**
	 * la setarea atributului x al unui nod sa se seteze cu aceeasi valoare si nodurile 
	 * fiu (! Se va testa existenta nodului fiu si apoi se va seta valoarea acestuia).
	 * @param x primeste ca argument o variabila de tipul double
	 */
	
	public void setX(double x) {
		this.x = x;
		if(this.nd!=null)
			this.nd.x=x;
		if(this.ns!=null)
			this.ns.x=x;
		}
	
	/**
	 * Metoda acceptVisitor are ca parametru un obiect de tip Visitor si nu returneaza
	 * nimic. A accepta un visitor inseamna de fapt a apela o metoda a visitorului pentru
	 * vizitarea nodului curent. In acest scop a fost cosntruita metoda visit(Nod n).
	 * Clasa de tip abstract Visitor trebuie sa furnizeze metode de inspectare pentru
	 */
	
	public void acceptVisitor(Visitor v){
		v.visit(this);
	}
	
	/**
	 * Metodele calcul(), derivare(),calculDerivata(),toString() vor fi metode abstracte
	 */
	
	public abstract double calcul();
	public abstract String derivare();
	public abstract double calculDerivata();
	public abstract String toString();
	public  abstract double calculeazaValoare();
	}